﻿#include "qslabel.h"
#include"controlwidget.h"
#include<QPalette>
#include <QApplication>
#include <QDesktopWidget>
#include <QHBoxLayout>
#include <QDateTime>
#include <QDebug>
#include"screen.h"

using namespace Qt;

#define RECT_CIRCLE_RADIUS 0

QSLabel::QSLabel(QWidget* parent)
    :QWidget(parent)
{
    parentScreen =(Screen*) parent;
    oldPoint = QPoint(0,0);
    ispressed=false;

    setWindowFlags(Qt::FramelessWindowHint);//无边框
    setAttribute(Qt::WA_TranslucentBackground, true);

    setContextMenuPolicy(Qt::NoContextMenu);

    setMouseTracking(true);

    int ratio = QApplication::desktop()->devicePixelRatio();

    m_ImageEditer = new ImageEditer(this);
    m_ImageEditer->setCurrentSize(3 * ratio);
    m_ImageEditer->setCurrentColor(Qt::red);

    PenSetting* pSetting = parentScreen->getPensetting();

    connect(m_ImageEditer,&ImageEditer::cliped,this,&QSLabel::on_cliped);
    connect(m_ImageEditer,&ImageEditer::undoEnableChanged,this,[=](bool undoEnable){
        parentScreen->setUndoEnable(undoEnable);
    });

    connect(pSetting,&PenSetting::sizeChanged,this,[=](PenSize size){
        int ps = 3 * ratio;
        if (size == PS_SMALL) {
            ps =  1 * ratio;
        }else if(size == PS_NORMAL) {
            ps =  3 * ratio;
        }else if (size == PS_LARGE){
            ps =  5 * ratio;
        }

        m_ImageEditer->setCurrentSize(ps);
    });

    connect(pSetting,&PenSetting::colorChanged,this,[=](QColor color){
        m_ImageEditer->setCurrentColor(color);
    });

    QHBoxLayout *layout = new QHBoxLayout(this);    //在control上建立水平布局
    layout->addWidget(m_ImageEditer);         //将控制窗口应用于水平布局
    layout->setContentsMargins(RECT_CIRCLE_RADIUS, RECT_CIRCLE_RADIUS, RECT_CIRCLE_RADIUS, RECT_CIRCLE_RADIUS);
    setLayout(layout);
}

void QSLabel::setOriginPixmap(QPixmap originPainting){
    originPixmap = originPainting;
}

void QSLabel::mouseMoveEvent(QMouseEvent *event)
{
    if(m_ImageEditer->isEditing()){
        return;
    }

    if(ispressed) {
        setCursor(OpenHandCursor);
    }
    
    QPoint gloPoint = mapToParent(event->pos());
    // left upper
    QPoint pt_lu = mapToParent(rect().topLeft());
    // left lower
    QPoint pt_ll = mapToParent(rect().bottomLeft());
    // right lower
    QPoint pt_rl = mapToParent(rect().bottomRight());
    // right upper
    QPoint pt_ru = mapToParent(rect().topRight());

    if(ispressed)
    {
        if(m_direction != NONE) {
            qDebug()<<"direction != none: "<< m_direction;
            
            const int& global_x = gloPoint.x();
            /// 鼠标进行拖拉拽
            switch(m_direction) {
            case LEFT:
                return slotMouseChange(global_x, pt_ll.y() + 1);
            case RIGHT:
                return slotMouseChange(global_x, pt_rl.y() + 1);
            case UPPER:
                qDebug()<<"LOWER: "<<pt_lu.x();
                qDebug()<<"pt_lu.x(): "<<pt_lu.x();
                return slotMouseChange(pt_lu.x(), gloPoint.y());
            case LOWER:
                qDebug()<<"LOWER: "<<pt_lu.x();
                return slotMouseChange(pt_rl.x() + 1, gloPoint.y());
            case LEFTUPPER:
            case RIGHTUPPER:
            case LEFTLOWER:
            case RIGHTLOWER:
                return slotMouseChange(global_x, gloPoint.y());
            default:
                break;
            }
        }else{
            QPoint point = event->pos();
            int x = point.x();
            int y = point.y();

            if(x <= RECT_CIRCLE_RADIUS){
                x = RECT_CIRCLE_RADIUS + 1;
            }

            if(y <= RECT_CIRCLE_RADIUS){
                y = RECT_CIRCLE_RADIUS + 1;
            }

            if(x >= this->width() - 2 * RECT_CIRCLE_RADIUS){
                x = this->width() - 2 * RECT_CIRCLE_RADIUS -1;
            }

            if(y >= this->height() - 2 * RECT_CIRCLE_RADIUS){
                y = this->height() - 2 * RECT_CIRCLE_RADIUS -1;
            }

            point = QPoint(x,y);

            {
                /////////////
                int ratio=QApplication::desktop()->devicePixelRatio();
                //if(ratio>1)
                //    ratio=ratio*2;
                /// 窗口的移动
                static QPoint oldPos=QPoint(0,0);
                
                /// 如果移到了屏幕右下角，且还在向右下角移动
                if(pos().x()+rect().width()>=originPixmap.width()/ratio&&oldPos.x()-event->globalPos().x()<0
                        &&pos().y()+rect().height()>=originPixmap.height()/ratio&&oldPos.y()-event->globalPos().y()<0)
                {
                    move(originPixmap.width()/ratio-rect().width(),originPixmap.height()/ratio-rect().height());
                }
                /// 如果移到了屏幕右上角，且还在向右上角移动
                else if(pos().x()+rect().width()>=originPixmap.width()/ratio&&oldPos.x()-event->globalPos().x()<0
                        &&pos().y()<=0&&oldPos.y()-event->globalPos().y()>0)
                {
                    move(originPixmap.width()/ratio-rect().width(),0);
                }
                /// 如果移到了屏幕左下角，且还在向左下角移动
                else if(pos().x()<=0&&oldPos.x()-event->globalPos().x()>0
                        &&pos().y()+rect().height()>=originPixmap.height()/ratio&&oldPos.y()-event->globalPos().y()<0)
                {
                    move(0,originPixmap.height()/ratio-rect().height());
                }
                /// 如果移到了屏幕左上角，且还在向左上角移动
                else if(pos().x()<=0&&oldPos.x()-event->globalPos().x()>0
                        &&pos().y()<=0&&oldPos.y()-event->globalPos().y()>0)
                {
                    move(0,0);
                }
                /// 如果移到了屏幕最右边，且还在向右移动
                else if(pos().x()+rect().width()>=originPixmap.width()/ratio&&oldPos.x()-event->globalPos().x()<0)
                {
                    move(originPixmap.width()/ratio-rect().width(),event->globalPos().y() - movePoint.y());
                }
                /// 如果移到了屏幕最下边，且还在向下移动
                else if(pos().y()+rect().height()>=originPixmap.height()/ratio&&oldPos.y()-event->globalPos().y()<0)
                {
                    move(event->globalPos().x() - movePoint.x(),originPixmap.height()/ratio-rect().height());
                }
                /// 如果移到了屏幕最左边，且还在向左移动
                else if(pos().x()<=0&&oldPos.x()-event->globalPos().x()>0)
                {
                    move(0,event->globalPos().y() - movePoint.y());
                }
                /// 如果移到了屏幕最上边，且还在向上移动
                else if(pos().y()<=0&&oldPos.y()-event->globalPos().y()>0)
                {
                    move(event->globalPos().x() - movePoint.x(),0);
                }
                else
                {
                    move(event->globalPos() - movePoint);
                }

                parentScreen->grabImage();
                parentScreen->moveControls();
                /////////////
                
                movePoint = event->globalPos() - pos();
                oldPoint = event->globalPos();
                oldPos = oldPoint;
                event->accept();
            }
     
            updateNow();
        }
    }else{
        if(m_ImageEditer->isEditing()){
            m_direction = NONE;
        }else{
            /// 检查鼠标鼠标方向
            m_direction = getRegion(gloPoint);

            /// 根据方位判断拖拉对应支点
            switch(m_direction) {
            case NONE:
            case RIGHT:
            case RIGHTLOWER:
                m_originPoint = pt_lu;
                break;
            case RIGHTUPPER:
                m_originPoint = pt_ll;
                break;
            case LEFT:
            case LEFTLOWER:
                m_originPoint = pt_ru;
                break;
            case LEFTUPPER:
            case UPPER:
                m_originPoint = pt_rl;
                break;
            case LOWER:
                m_originPoint = pt_lu;
                break;
            }
        }
    }

    m_currentRect = geometry();
}

void QSLabel::slotMouseChange(int x, int y) {
    if(isHidden())
    {
        show();
    }
    if (x < 0 || y < 0) {
        return;
    }
    
    const int& rx = (x >= m_originPoint.x()) ? m_originPoint.x() : x ;
    const int& ry = (y >= m_originPoint.y()) ? m_originPoint.y()  : y;
    const int& rw = abs(x - m_originPoint.x());
    const int& rh = abs(y - m_originPoint.y());

    // 改变大小
    m_currentRect = QRect(rx, ry, rw, rh);
    
    this->setGeometry(m_currentRect);
    parentScreen->grabImage();
    parentScreen->moveControls();
}

void QSLabel::mousePressEvent(QMouseEvent *event)
{
    if(m_ImageEditer->isEditing()){
        return;
    }

    if (event->button() == Qt::LeftButton) {
        ispressed = true;
        
        if(m_direction != NONE) {
            this->mouseGrabber();
        }
        
        movePoint = event->globalPos() - pos();
    }
    
    startPoint=event->pos();
    endPoint=event->pos();
    movePoint = event->globalPos() - pos();
}

void QSLabel::mouseReleaseEvent(QMouseEvent *event)
{
    static qint64 lastTime = 0;
    qint64 curTime = QDateTime::currentDateTime().toMSecsSinceEpoch();

    qDebug() << "QSLabel::mousePressEvent" << curTime << lastTime;
    if(curTime-lastTime < 300){
        parentScreen->complete();
        return;
    }

    lastTime = curTime;

    qDebug() << "QSLabel::mouseReleaseEvent";
    if(m_ImageEditer->isEditing()){
        return;
    }

    if (event->button() == Qt::LeftButton) {
        ispressed = false;
        if(m_direction != NONE) {
            setCursor(QCursor(Qt::SizeAllCursor));
            return;
        }
        
        updateNow();
    }
}

void QSLabel::mouseDoubleClickEvent(QMouseEvent *event)
{
    qDebug() << "QSLabel::mouseDoubleClickEvent" ;
    if(event->button() == Qt::LeftButton){
        parentScreen->complete();
    }
}

void QSLabel::paintEvent(QPaintEvent *event)
{
    QWidget::paintEvent(event);

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    int ratio=QApplication::desktop()->devicePixelRatio();

    QRect rect = this->rect();

    QPen pen;
    pen.setColor(QColor(87,255,158));
    pen.setWidth(RECT_CIRCLE_RADIUS);
    painter.setPen(pen);
    
    rect.adjust(RECT_CIRCLE_RADIUS, RECT_CIRCLE_RADIUS, -RECT_CIRCLE_RADIUS, -RECT_CIRCLE_RADIUS);
    painter.drawRect(rect);
    
    /// 绘制八个点
    pen.setWidth(5);
    pen.setColor(QColor(87,255,158));
    painter.setPen(pen);
    painter.drawPoints(m_listMarker);
}

void QSLabel::showEvent(QShowEvent *)
{
    isInit = true;
}

void QSLabel::closeEvent(QCloseEvent *)
{
    isInit = false;
}

void QSLabel::resizeEvent(QResizeEvent *) {
    qDebug()<<"resizeEvent";
    
    m_listMarker.clear();

    //// 角点
    m_listMarker.push_back(QPoint(RECT_CIRCLE_RADIUS, RECT_CIRCLE_RADIUS));
    m_listMarker.push_back(QPoint(width() - RECT_CIRCLE_RADIUS, RECT_CIRCLE_RADIUS));
    m_listMarker.push_back(QPoint(RECT_CIRCLE_RADIUS, height() - RECT_CIRCLE_RADIUS));
    m_listMarker.push_back(QPoint(width() - RECT_CIRCLE_RADIUS, height() - RECT_CIRCLE_RADIUS));

    //// 中点
    m_listMarker.push_back(QPoint((width() >> 1), RECT_CIRCLE_RADIUS));
    m_listMarker.push_back(QPoint((width() >> 1), height() - RECT_CIRCLE_RADIUS));
    m_listMarker.push_back(QPoint(RECT_CIRCLE_RADIUS, (height() >> 1)));
    m_listMarker.push_back(QPoint(width() - RECT_CIRCLE_RADIUS, (height() >> 1)));
}

void QSLabel::setimagetolabel(const QImage &image)
{
    m_ImageEditer->setimagetolabel(image);

    endPoint=QPoint(0,0);
    startPoint=QPoint(0,0);
}

void QSLabel::undo()
{
    m_ImageEditer->undo();
}

void QSLabel::setdrawlineenable()
{
    m_ImageEditer->setdrawlineenable();
}

void QSLabel::setrectangleenable()
{
    m_ImageEditer->setrectangleenable();
}

void QSLabel::setdrawarrowenable()
{
    m_ImageEditer->setdrawarrowenable();
}

void QSLabel::setroundenable()
{
    m_ImageEditer->setroundenable();
}

void QSLabel::settexteditenable()
{
    m_ImageEditer->settexteditenable();
}

void QSLabel::setdrawmosaicnable()
{
    m_ImageEditer->setdrawmosaicnable();
}

void QSLabel::setdrawfacenable()
{
    m_ImageEditer->setdrawfacenable();
}

void QSLabel::setclipable()
{
    m_ImageEditer->setclipable();
}

QPixmap QSLabel::resultimage()
{
    return m_ImageEditer->resultimage();
}

void QSLabel::updateNow()
{
    this->update();
}

void QSLabel::on_cliped(QRect rect)
{
    QPoint topLeft = rect.topLeft();
    topLeft = parentScreen->mapFromGlobal(topLeft);
    this->setGeometry(topLeft.x(),topLeft.y(),rect.width(),rect.height());
    parentScreen->grabImage();
    parentScreen->moveControls();
}

QSLabel::DIRECTION QSLabel::getRegion(const QPoint &cursor)
{
    if (!isInit) {
        return NONE;
    }
    
    QSLabel::DIRECTION ret_dir = NONE;
    // left upper
    QPoint pt_lu = mapToParent(rect().topLeft());
    // right lower
    QPoint pt_rl = mapToParent(rect().bottomRight());

    int x = cursor.x();
    int y = cursor.y();

    /// 获得鼠标当前所处窗口的边界方向
    if(pt_lu.x() + PADDING_ >= x
    && pt_lu.x() <= x
    && pt_lu.y() + PADDING_ >= y
    && pt_lu.y() <= y) {
        // 左上角
        ret_dir = LEFTUPPER;
        this->setCursor(QCursor(Qt::SizeFDiagCursor));
    } else if(x >= pt_rl.x() - PADDING_
           && x <= pt_rl.x()
           && y >= pt_rl.y() - PADDING_
           && y <= pt_rl.y()) {
        // 右下角
        ret_dir = RIGHTLOWER;
        this->setCursor(QCursor(Qt::SizeFDiagCursor));
    } else if(x <= pt_lu.x() + PADDING_
           && x >= pt_lu.x()
           && y >= pt_rl.y() - PADDING_
           && y <= pt_rl.y()) {
        // 左下角
        ret_dir = LEFTLOWER;
        this->setCursor(QCursor(Qt::SizeBDiagCursor));
    } else if(x <= pt_rl.x()
           && x >= pt_rl.x() - PADDING_
           && y >= pt_lu.y()
           && y <= pt_lu.y() + PADDING_) {
        // 右上角
        ret_dir = RIGHTUPPER;
        this->setCursor(QCursor(Qt::SizeBDiagCursor));
    } else if(x <= pt_lu.x() + PADDING_
           && x >= pt_lu.x()) {
        // 左边
        ret_dir = LEFT;
        this->setCursor(QCursor(Qt::SizeHorCursor));
    } else if( x <= pt_rl.x()
            && x >= pt_rl.x() - PADDING_) {
        // 右边
        ret_dir = RIGHT;
        this->setCursor(QCursor(Qt::SizeHorCursor));
    }else if(y >= pt_lu.y()
          && y <= pt_lu.y() + PADDING_){
        // 上边
        ret_dir = UPPER;
        this->setCursor(QCursor(Qt::SizeVerCursor));
    } else if(y <= pt_rl.y()
           && y >= pt_rl.y() - PADDING_) {
        // 下边
        ret_dir = LOWER;
        this->setCursor(QCursor(Qt::SizeVerCursor));
    }else {
        // 默认
        ret_dir = NONE;
        this->setCursor(QCursor(Qt::SizeAllCursor));
    }
    return ret_dir;
}
